/**
 *                            License
 * THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS  
 * CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). 
 * THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW.  
 * ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR  
 * COPYRIGHT LAW IS PROHIBITED.
 * 
 * BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND  
 * AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE  
 * MAY BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED 
 * HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS.
 * 
 */
package l1j.server.server.model;

import static l1j.server.server.model.skill.L1SkillId.AWAKEN_ANTHARAS;
import static l1j.server.server.model.skill.L1SkillId.AWAKEN_FAFURION;
import static l1j.server.server.model.skill.L1SkillId.AWAKEN_VALAKAS;

import java.util.List;
import java.util.StringTokenizer;

import l1j.server.server.datatables.ArmorSetTable;
import l1j.server.server.model.Instance.L1ItemInstance;
import l1j.server.server.model.Instance.L1PcInstance;
import l1j.server.server.serverpackets.S_ServerMessage;
import l1j.server.server.serverpackets.S_SystemMessage;
import l1j.server.server.templates.L1ArmorSets;
import l1j.server.server.utils.collections.Lists;

public abstract class L1ArmorSet {
	public abstract void giveArmorSetEffect(L1PcInstance pc, int enchantLevel);
	
	public abstract void cancelArmorSetEffect(L1PcInstance pc, int enchantLevel);
	
	public abstract int getEffect_Enchant_Level();

	public abstract boolean isValid(L1PcInstance pc, L1ItemInstance item);

	public abstract boolean isPartOfSet(int id);

	public abstract boolean isEquippedRingOfArmorSet(L1PcInstance pc);

	public static List<L1ArmorSet> getAllSet() {
		return _allSet;
	}

	private static List<L1ArmorSet> _allSet = Lists.newList();

	/*
	 * ここで初期化してしまうのはいかがなものか・・・美しくない気がする
	 */
	static {
		L1ArmorSetImpl impl;

		for (L1ArmorSets armorSets : ArmorSetTable.getInstance().getAllList()) {
			try {

				impl = new L1ArmorSetImpl(getArray(armorSets.getSets(), ",")
						, armorSets.getEffectEnchantLevel(), armorSets.getEffectStartNumber());
				impl.addArmorSetEffect(new ArmorSetEffect(armorSets.getEffectGroupsOne()
						, armorSets.getEffectGroupsTwo(),armorSets.getEffectGroupsThree(),armorSets.getEffectGroupsFour()
						, armorSets.getEffectAc(), armorSets.getEffectHp(), armorSets.getEffectMp()
						, armorSets.getEffectHpr(), armorSets.getEffectMpr(), armorSets.getEffectMr()
						, armorSets.getEffectHitHpr(), armorSets.getEffectHit(), armorSets.getEffectDmg()
						, armorSets.getEffectSp(), armorSets.getEffectStr(), armorSets.getEffectDex()
						, armorSets.getEffectCon(), armorSets.getEffectWis(), armorSets.getEffectCha()
						, armorSets.getEffectInt(), armorSets.getEffectDefendWater(), armorSets.getEffectDefendWind()
						, armorSets.getEffectDefendFire(), armorSets.getEffectDefendEarth()));
				if (armorSets.getPolyId() != -1) {
					impl.addPolyEffect(new PolymorphEffect(armorSets.getPolyId()));
				}
				_allSet.add(impl);
			} catch (Exception ex) {
				ex.printStackTrace();
			}
		}
	}

	private static int[] getArray(String s, String sToken) {
		StringTokenizer st = new StringTokenizer(s, sToken);
		int size = st.countTokens();
		String temp = null;
		int[] array = new int[size];
		for (int i = 0; i < size; i++) {
			temp = st.nextToken();
			array[i] = Integer.parseInt(temp);
		}
		return array;
	}
}

interface L1ArmorSetEffect {
	public void giveEffect(L1PcInstance pc, int equipArmorOfSet, int enchantLevel);

	public void cancelEffect(L1PcInstance pc, int equipArmorOfSet, int enchantLevel);
}

class L1ArmorSetImpl extends L1ArmorSet {
	private final int _ids[];
	
	private final int _effect_enchant_level;
	
	private final int _effect_start_number;
	
	private int _effect_armorset_value = 0;
	
	private L1ArmorSetEffect _armorSetEffect = null;
	
	private L1ArmorSetEffect _polyEffect = null;
	
	protected L1ArmorSetImpl(int ids[], int effect_enchant_level, int effect_start_number) {
		_ids = ids;
		_effect_start_number = effect_start_number;
		_effect_enchant_level = effect_enchant_level;
	}

	public void addArmorSetEffect(L1ArmorSetEffect effect) {
		_armorSetEffect = effect;
	}
	
	public void addPolyEffect(L1ArmorSetEffect effect) {
		_polyEffect = effect;
	}
	
	public int getEffect_Enchant_Level() {
		return _effect_enchant_level;
	}
	
	@Override
	public void giveArmorSetEffect(L1PcInstance pc, int enchantLevel) {
		_armorSetEffect.giveEffect(pc, pc.getInventory().
				checkEquipped(_ids, _effect_start_number, enchantLevel), _effect_armorset_value);
		if (pc.getInventory().checkEquipped(_ids) && _polyEffect != null) {
			_polyEffect.giveEffect(pc, pc.getInventory().
					checkEquipped(_ids, _effect_start_number, enchantLevel), _effect_armorset_value);
		}
	}
	
	public void cancelArmorSetEffect(L1PcInstance pc, int enchantLevel) {
		_armorSetEffect.cancelEffect(pc, pc.getInventory().
				checkEquipped(_ids, _effect_start_number, enchantLevel), _effect_armorset_value);
		if (!pc.getInventory().checkEquipped(_ids) && _polyEffect != null) {
			_polyEffect.cancelEffect(pc, pc.getInventory().
					checkEquipped(_ids, _effect_start_number, enchantLevel), _effect_armorset_value);
		}
	}

	@Override
	public final boolean isValid(L1PcInstance pc, L1ItemInstance item) {
		_effect_armorset_value = item.getEnchantLevel() - _effect_enchant_level;
		if (_effect_armorset_value < 0
				|| pc.getInventory().checkEquipped(_ids, _effect_start_number, item.getEnchantLevel()) < 0) {
			return false;
		}
		return true;
	}

	@Override
	public boolean isPartOfSet(int id) {
		for (int i : _ids) {
			if (id == i) {
				return true;
			}
		}
		return false;
	}

	@Override
	public boolean isEquippedRingOfArmorSet(L1PcInstance pc) {
		L1PcInventory pcInventory = pc.getInventory();
		L1ItemInstance armor = null;
		boolean isSetContainRing = false;

		// セット装備にリングが含まれているか調べる
		for (int id : _ids) {
			armor = pcInventory.findItemId(id);
			if ((armor.isArmor())
					&& (armor.getItem().getType() == 9)) { // ring
				isSetContainRing = true;
				break;
			}
		}

		// リングを2つ装備していて、それが両方セット装備か調べる
		if ((armor != null) && isSetContainRing) {
			int itemId = armor.getItem().getItemId();
			if (pcInventory.getTypeEquipped(2, 9) == 2) {
				L1ItemInstance ring[] = new L1ItemInstance[2];
				ring = pcInventory.getRingEquipped();
				if ((ring[0].getItem().getItemId() == itemId)
						&& (ring[1].getItem().getItemId() == itemId)) {
					return true;
				}
			}
		}
		return false;
	}

}

class ArmorSetEffect implements L1ArmorSetEffect {
	
	private final String[] _effect_groups_1;
	
	private final String[] _effect_groups_2;
	
	private final String[] _effect_groups_3;
	
	private final String[] _effect_groups_4;
	
	private final String[] _effect_1_ac;
	
	private final String[] _effect_2_hp;
	
	private final String[] _effect_3_mp;
	
	private final String[] _effect_4_hpr;
	
	private final String[] _effect_5_mpr;
	
	private final String[] _effect_6_mr;
	
	private final String[] _effect_7_hit_hpr;
	
	private final String[] _effect_8_hit;
	
	private final String[] _effect_9_dmg;
	
	private final String[] _effect_10_sp;
	
	private final String[] _effect_11_str;
	
	private final String[] _effect_12_dex;
	
	private final String[] _effect_13_con;
	
	private final String[] _effect_14_wis;
	
	private final String[] _effect_15_cha;
	
	private final String[] _effect_16_int;
	
	private final String[] _effect_17_defend_water;
	
	private final String[] _effect_18_defend_wind;
	
	private final String[] _effect_19_defend_fire;
	
	private final String[] _effect_20_defend_earth;
	
	public ArmorSetEffect(String[] effect_groups_1, String[] effect_groups_2
			, String[] effect_groups_3, String[] effect_groups_4 
			, String[] effect_1_ac, String[] effect_2_hp, String[] effect_3_mp
			, String[] effect_4_hpr, String[] effect_5_mpr, String[] effect_6_mr
			, String[] effect_7_hit_hpr, String[] effect_8_hit, String[] effect_9_dmg
			, String[] effect_10_sp, String[] effect_11_str, String[] effect_12_dex
			, String[] effect_13_con, String[] effect_14_wis, String[] effect_15_cha
			, String[] effect_16_int, String[] effect_17_defend_water, String[] effect_18_defend_wind
			, String[] effect_19_defend_fire, String[] effect_20_defend_earth) {
		_effect_groups_1 = effect_groups_1;
		_effect_groups_2 = effect_groups_2;
		_effect_groups_3 = effect_groups_3;
		_effect_groups_4 = effect_groups_4;
		_effect_1_ac = effect_1_ac;
		_effect_2_hp = effect_2_hp;
		_effect_3_mp = effect_3_mp;
		_effect_4_hpr = effect_4_hpr;
		_effect_5_mpr = effect_5_mpr;
		_effect_6_mr = effect_6_mr;
		_effect_7_hit_hpr = effect_7_hit_hpr;
		_effect_8_hit = effect_8_hit;
		_effect_9_dmg = effect_9_dmg;
		_effect_10_sp = effect_10_sp;
		_effect_11_str = effect_11_str;
		_effect_12_dex = effect_12_dex;
		_effect_13_con = effect_13_con;
		_effect_14_wis = effect_14_wis;
		_effect_15_cha = effect_15_cha;
		_effect_16_int = effect_16_int;
		_effect_17_defend_water = effect_17_defend_water;
		_effect_18_defend_wind = effect_18_defend_wind;
		_effect_19_defend_fire = effect_19_defend_fire;
		_effect_20_defend_earth = effect_20_defend_earth;
	}
	
	@Override
	public void giveEffect(L1PcInstance pc, int equipArmorOfSet, int effect_armorset_value) {
		int times = 0;
		String[] effect_groups = null;
		if (equipArmorOfSet == 0) {
			times = _effect_groups_1.length;
			effect_groups = _effect_groups_1;
		} else if (equipArmorOfSet == 1) {
			times = _effect_groups_2.length;
			effect_groups = _effect_groups_2;
		} else if (equipArmorOfSet == 2) {
			times = _effect_groups_3.length;
			effect_groups = _effect_groups_3;
		} else if (equipArmorOfSet == 3) {
			times = _effect_groups_4.length;
			effect_groups = _effect_groups_4;
		}
		for(int i = 0; i < times; i++) {
			switch(Integer.parseInt(effect_groups[i])) {
			case 1:
				pc.addAc(Integer.parseInt(_effect_1_ac[effect_armorset_value]));
				pc.sendPackets(new S_SystemMessage("得到套裝效果: 物理防禦 " + _effect_1_ac[effect_armorset_value]));
				break;
			case 2:
				pc.addMaxHp(Integer.parseInt(_effect_2_hp[effect_armorset_value]));
				pc.sendPackets(new S_SystemMessage("得到套裝效果: 最大HP " + _effect_2_hp[effect_armorset_value]));
				break;
			case 3:
				pc.addMaxMp(Integer.parseInt(_effect_3_mp[effect_armorset_value]));
				pc.sendPackets(new S_SystemMessage("得到套裝效果: 最大MP " + _effect_3_mp[effect_armorset_value]));
				break;
			case 4:
				pc.addHpr(Integer.parseInt(_effect_4_hpr[effect_armorset_value]));
				pc.sendPackets(new S_SystemMessage("得到套裝效果: 回血 " + _effect_4_hpr[effect_armorset_value]));
				break;
			case 5:
				pc.addMpr(Integer.parseInt(_effect_5_mpr[effect_armorset_value]));
				pc.sendPackets(new S_SystemMessage("得到套裝效果: 回魔 " + _effect_5_mpr[effect_armorset_value]));
				break;
			case 6:
				pc.addMr(Integer.parseInt(_effect_6_mr[effect_armorset_value]));
				pc.sendPackets(new S_SystemMessage("得到套裝效果: 魔法防禦 " + _effect_6_mr[effect_armorset_value]));
				break;
			case 7:
				pc.addHitRegenerationHpByArmor(Integer.parseInt(_effect_7_hit_hpr[effect_armorset_value]));
				pc.sendPackets(new S_SystemMessage("得到套裝效果: 擊中回血 " + _effect_7_hit_hpr[effect_armorset_value]));
				break;
			case 8:
				pc.addHitModifierByArmor(Integer.parseInt(_effect_8_hit[effect_armorset_value]));
				pc.addBowHitModifierByArmor(Integer.parseInt(_effect_8_hit[effect_armorset_value]));
				pc.sendPackets(new S_SystemMessage("得到套裝效果: 命中率 " + _effect_8_hit[effect_armorset_value]));
				break;
			case 9:
				pc.addDmgModifierByArmor(Integer.parseInt(_effect_9_dmg[effect_armorset_value]));
				pc.addBowDmgModifierByArmor(Integer.parseInt(_effect_9_dmg[effect_armorset_value]));
				pc.sendPackets(new S_SystemMessage("得到套裝效果: 物理攻擊 " + _effect_9_dmg[effect_armorset_value]));
				break;
			case 10:
				pc.addSp(Integer.parseInt(_effect_10_sp[effect_armorset_value]));
				pc.sendPackets(new S_SystemMessage("得到套裝效果: 魔法攻擊 " + _effect_10_sp[effect_armorset_value]));
				break;
			case 11:
				pc.addStr(Integer.parseInt(_effect_11_str[effect_armorset_value]));
				pc.sendPackets(new S_SystemMessage("得到套裝效果: 力量 " + _effect_11_str[effect_armorset_value]));
				break;
			case 12:
				pc.addDex(Integer.parseInt(_effect_12_dex[effect_armorset_value]));
				pc.sendPackets(new S_SystemMessage("得到套裝效果: 敏捷 " + _effect_12_dex[effect_armorset_value]));
				break;
			case 13:
				pc.addCon(Integer.parseInt(_effect_13_con[effect_armorset_value]));
				pc.sendPackets(new S_SystemMessage("得到套裝效果: 體質 " + _effect_13_con[effect_armorset_value]));
				break;
			case 14:
				pc.addWis(Integer.parseInt(_effect_14_wis[effect_armorset_value]));
				pc.sendPackets(new S_SystemMessage("得到套裝效果: 精神 " + _effect_14_wis[effect_armorset_value]));
				break;
			case 15:
				pc.addCha(Integer.parseInt(_effect_15_cha[effect_armorset_value]));
				pc.sendPackets(new S_SystemMessage("得到套裝效果: 魅力 " + _effect_15_cha[effect_armorset_value]));
				break;
			case 16:
				pc.addInt(Integer.parseInt(_effect_16_int[effect_armorset_value]));
				pc.sendPackets(new S_SystemMessage("得到套裝效果: 智力 " + _effect_16_int[effect_armorset_value]));
				break;
			case 17:
				pc.addWater(Integer.parseInt(_effect_17_defend_water[effect_armorset_value]));
				pc.sendPackets(new S_SystemMessage("得到套裝效果: 水屬抗性 " + _effect_17_defend_water[effect_armorset_value]));
				break;
			case 18:
				pc.addWind(Integer.parseInt(_effect_18_defend_wind[effect_armorset_value]));
				pc.sendPackets(new S_SystemMessage("得到套裝效果: 風屬抗性 " + _effect_18_defend_wind[effect_armorset_value]));
				break;
			case 19:
				pc.addFire(Integer.parseInt(_effect_19_defend_fire[effect_armorset_value]));
				pc.sendPackets(new S_SystemMessage("得到套裝效果: 火屬抗性 " + _effect_19_defend_fire[effect_armorset_value]));
				break;
			case 20:
				pc.addEarth(Integer.parseInt(_effect_20_defend_earth[effect_armorset_value]));
				pc.sendPackets(new S_SystemMessage("得到套裝效果: 地屬抗性 " + _effect_20_defend_earth[effect_armorset_value]));
				break;
			default:
				//
				break;
			}
		}
	}
	
	@Override
	public void cancelEffect(L1PcInstance pc, int equipArmorOfSet, int effect_armorset_value) {
		int times = 0;
		String[] effect_groups = null;
		if (equipArmorOfSet == -1) {
			times = _effect_groups_1.length;
			effect_groups = _effect_groups_1;
		} else if (equipArmorOfSet == 0) {
			times = _effect_groups_2.length;
			effect_groups = _effect_groups_2;
		} else if (equipArmorOfSet == 1) {
			times = _effect_groups_3.length;
			effect_groups = _effect_groups_3;
		} else if (equipArmorOfSet == 2) {
			times = _effect_groups_4.length;
			effect_groups = _effect_groups_4;
		}
		for(int i = 0; i < times; i++) {
			switch(Integer.parseInt(effect_groups[i])) {
			case 1:
				pc.addAc(-Integer.parseInt(_effect_1_ac[effect_armorset_value]));
				pc.sendPackets(new S_SystemMessage("解除套裝效果: 物理防禦 " 
						+ -Integer.parseInt(_effect_1_ac[effect_armorset_value])));
				break;
			case 2:
				pc.addMaxHp(-Integer.parseInt(_effect_2_hp[effect_armorset_value]));
				pc.sendPackets(new S_SystemMessage("解除套裝效果: 最大HP " 
						+ -Integer.parseInt(_effect_2_hp[effect_armorset_value])));
				break;
			case 3:
				pc.addMaxMp(-Integer.parseInt(_effect_3_mp[effect_armorset_value]));
				pc.sendPackets(new S_SystemMessage("解除套裝效果: 最大MP " 
						+ -Integer.parseInt(_effect_3_mp[effect_armorset_value])));
				break;
			case 4:
				pc.addHpr(-Integer.parseInt(_effect_4_hpr[effect_armorset_value]));
				pc.sendPackets(new S_SystemMessage("解除套裝效果: 回血 " 
						+ -Integer.parseInt(_effect_4_hpr[effect_armorset_value])));
				break;
			case 5:
				pc.addMpr(-Integer.parseInt(_effect_5_mpr[effect_armorset_value]));
				pc.sendPackets(new S_SystemMessage("解除套裝效果: 回魔 " 
						+ -Integer.parseInt(_effect_5_mpr[effect_armorset_value])));
				break;
			case 6:
				pc.addMr(-Integer.parseInt(_effect_6_mr[effect_armorset_value]));
				pc.sendPackets(new S_SystemMessage("解除套裝效果: 魔法防禦 " 
						+ -Integer.parseInt(_effect_6_mr[effect_armorset_value])));
				break;
			case 7:
				pc.addHitRegenerationHpByArmor(-Integer.parseInt(_effect_7_hit_hpr[effect_armorset_value]));
				pc.sendPackets(new S_SystemMessage("解除套裝效果: 擊中回血 " 
						+ -Integer.parseInt(_effect_7_hit_hpr[effect_armorset_value])));
				break;
			case 8:
				pc.addHitModifierByArmor(-Integer.parseInt(_effect_8_hit[effect_armorset_value]));
				pc.addBowHitModifierByArmor(-Integer.parseInt(_effect_8_hit[effect_armorset_value]));
				pc.sendPackets(new S_SystemMessage("解除套裝效果: 命中率 " 
						+ -Integer.parseInt(_effect_8_hit[effect_armorset_value])));
				break;
			case 9:
				pc.addDmgModifierByArmor(-Integer.parseInt(_effect_9_dmg[effect_armorset_value]));
				pc.addBowDmgModifierByArmor(-Integer.parseInt(_effect_9_dmg[effect_armorset_value]));
				pc.sendPackets(new S_SystemMessage("解除套裝效果: 物理攻擊 " 
						+ -Integer.parseInt(_effect_9_dmg[effect_armorset_value])));
				break;
			case 10:
				pc.addSp(-Integer.parseInt(_effect_10_sp[effect_armorset_value]));
				pc.sendPackets(new S_SystemMessage("解除套裝效果: 魔法攻擊 " 
						+ -Integer.parseInt(_effect_10_sp[effect_armorset_value])));
				break;
			case 11:
				pc.addStr(-Integer.parseInt(_effect_11_str[effect_armorset_value]));
				pc.sendPackets(new S_SystemMessage("解除套裝效果: 力量 " 
						+ -Integer.parseInt(_effect_11_str[effect_armorset_value])));
				break;
			case 12:
				pc.addDex(-Integer.parseInt(_effect_12_dex[effect_armorset_value]));
				pc.sendPackets(new S_SystemMessage("解除套裝效果: 敏捷 " 
						+ -Integer.parseInt(_effect_12_dex[effect_armorset_value])));
				break;
			case 13:
				pc.addCon(-Integer.parseInt(_effect_13_con[effect_armorset_value]));
				pc.sendPackets(new S_SystemMessage("解除套裝效果: 體質 " 
						+ -Integer.parseInt(_effect_13_con[effect_armorset_value])));
				break;
			case 14:
				pc.addWis(-Integer.parseInt(_effect_14_wis[effect_armorset_value]));
				pc.sendPackets(new S_SystemMessage("解除套裝效果: 精神 " 
						+ -Integer.parseInt(_effect_14_wis[effect_armorset_value])));
				break;
			case 15:
				pc.addCha(-Integer.parseInt(_effect_15_cha[effect_armorset_value]));
				pc.sendPackets(new S_SystemMessage("解除套裝效果: 魅力 " 
						+ -Integer.parseInt(_effect_15_cha[effect_armorset_value])));
				break;
			case 16:
				pc.addInt(-Integer.parseInt(_effect_16_int[effect_armorset_value]));
				pc.sendPackets(new S_SystemMessage("解除套裝效果: 智力 " 
						+ -Integer.parseInt(_effect_16_int[effect_armorset_value])));
				break;
			case 17:
				pc.addWater(-Integer.parseInt(_effect_17_defend_water[effect_armorset_value]));
				pc.sendPackets(new S_SystemMessage("解除套裝效果: 水屬抗性 " 
						+ -Integer.parseInt(_effect_17_defend_water[effect_armorset_value])));
				break;
			case 18:
				pc.addWind(-Integer.parseInt(_effect_18_defend_wind[effect_armorset_value]));
				pc.sendPackets(new S_SystemMessage("解除套裝效果: 風屬抗性 " 
						+ -Integer.parseInt(_effect_18_defend_wind[effect_armorset_value])));
				break;
			case 19:
				pc.addFire(-Integer.parseInt(_effect_19_defend_fire[effect_armorset_value]));
				pc.sendPackets(new S_SystemMessage("解除套裝效果: 火屬抗性 " 
						+ -Integer.parseInt(_effect_19_defend_fire[effect_armorset_value])));
				break;
			case 20:
				pc.addEarth(-Integer.parseInt(_effect_20_defend_earth[effect_armorset_value]));
				pc.sendPackets(new S_SystemMessage("解除套裝效果: 地屬抗性 " 
						+ -Integer.parseInt(_effect_20_defend_earth[effect_armorset_value])));
				break;
			default:
				//
				break;
			}
		}
	}
}

class PolymorphEffect implements L1ArmorSetEffect {
	private int _gfxId;

	public PolymorphEffect(int gfxId) {
		_gfxId = gfxId;
	}

	@Override
	public void giveEffect(L1PcInstance pc, int equipArmorOfSet, int enchantLevel) {
		int awakeSkillId = pc.getAwakeSkillId();
		if ((awakeSkillId == AWAKEN_ANTHARAS)
				|| (awakeSkillId == AWAKEN_FAFURION)
				|| (awakeSkillId == AWAKEN_VALAKAS)) {
			pc.sendPackets(new S_ServerMessage(1384)); // 現在の状態では変身できません。
			return;
		}
		if ((_gfxId == 6080) || (_gfxId == 6094)) {
			if (pc.get_sex() == 0) {
				_gfxId = 6094;
			} else {
				_gfxId = 6080;
			}
			if (!isRemainderOfCharge(pc)) { // 残チャージ数なし
				return;
			}
		}
		L1PolyMorph.doPoly(pc, _gfxId, 0, L1PolyMorph.MORPH_BY_ITEMMAGIC);
	}

	@Override
	public void cancelEffect(L1PcInstance pc, int equipArmorOfSet, int enchantLevel) {
		int awakeSkillId = pc.getAwakeSkillId();
		if ((awakeSkillId == AWAKEN_ANTHARAS)
				|| (awakeSkillId == AWAKEN_FAFURION)
				|| (awakeSkillId == AWAKEN_VALAKAS)) {
			pc.sendPackets(new S_ServerMessage(1384)); // 現在の状態では変身できません。
			return;
		}
		if (_gfxId == 6080) {
			if (pc.get_sex() == 0) {
				_gfxId = 6094;
			}
		}
		if (pc.getTempCharGfx() != _gfxId) {
			return;
		}
		L1PolyMorph.undoPoly(pc);
	}

	private boolean isRemainderOfCharge(L1PcInstance pc) {
		boolean isRemainderOfCharge = false;
		if (pc.getInventory().checkItem(20383, 1)) {
			L1ItemInstance item = pc.getInventory().findItemId(20383);
			if (item != null) {
				if (item.getChargeCount() != 0) {
					isRemainderOfCharge = true;
				}
			}
		}
		return isRemainderOfCharge;
	}

}
